<template>
    <!-- el-cascader el-cascader--mini -->
    <div class="w-100 tree-input-wrapper" :class="collapseTags ? 'fixHeight' : ''">
        <!-- placement="bottom" -->
        <el-popover ref="popover" width="400" trigger="click" :disabled="getDisabled">
            <!-- el-input el-input--mini el-input--suffix -->
            <div
                slot="reference"
                class="input-click-select w-100"
                :class="{
                    'showMore': !collapseTags,
                    'disabled': getDisabled,
                }"
                @click="onSelectClick"
            >
                <span v-show="showText" style="color: #606266">
                    <span
                        v-for="(item, index) in inputText"
                        :key="index"
                        :class="
                            multiple
                                ? 'el-tag el-tag--info el-tag--mini el-tag--light mr-4'
                                : ''
                        "
                    >{{ item | inputTextFilter(labelName, separator) }}</span>
                </span>
                <span v-show="!showText" class="color999">
                    {{ placeholder }}
                </span>
                <i
                    v-if="showText && !getDisabled"
                    class="el-icon-circle-close closIcon"
                    @click="clearHandle"
                />
            </div>
            <div class>
                <div class="my-8">
                    <el-input
                        v-if="filterable"
                        v-model="filterKey"
                        style="width: 200px; margin-right: 12px"
                        clearable
                        placeholder="请输入"
                    ></el-input>

                    <el-button
                        v-if="filterable"
                        class="mx-8"
                        type="primary"
                        size="mini"
                        @click="filterClick"
                    >搜索</el-button>
                </div>
                <div class="selectWrapper light-little-scroll">
                    <el-tree
                        ref="select"
                        v-show="treeModel === 'select'"
                        :show-checkbox="false"
                        :data="options"
                        node-key="id"
                        :props="{ isLeaf: 'isLeaf' }"
                        :highlight-current="true"
                        :default-checked-keys="checkedKeys"
                        :check-strictly="props.checkStrictly"
                        :lazy="props.lazy"
                        :load="props.lazyLoad"
                        :render-content="renderContent"
                        @current-change="currentChange"
                        @check-change="checkChange"
                        @node-click="handleNodeClick"
                    ></el-tree>
                    <el-tree
                        ref="filter"
                        v-show="treeModel === 'filter'"
                        :show-checkbox="false"
                        :data="filterOptions"
                        :default-expand-all="true"
                        node-key="id"
                        :props="{ isLeaf: 'isLeaf' }"
                        :highlight-current="true"
                        :default-checked-keys="checkedKeys"
                        :check-strictly="props.checkStrictly"
                        :render-content="renderContent"
                        @check-change="checkChange"
                        @current-change="currentChange"
                        @node-click="handleNodeClick"
                    ></el-tree>
                </div>
                 <div class="footer">
                    <el-button
                        class="ml-8"
                        type="primary"
                        size="mini"
                        @click="onConfirm"
                        >确定</el-button
                    >
                </div>
            </div>
        </el-popover>
    </div>
</template>
<script>
import _ from "lodash";
import { getPathByLeafId } from "@utils";
const MODE_TYPE = {
    select: "select",
    filter: "filter",
};
export default {
    name: "com-treeSelect",
    props: {
        disabled: {
            type: Boolean,
        },
        collapseTags: {
            type: Boolean,
            default: true,
        },
        filterable: {
            type: Boolean,
            default: false,
        },
        placeholder: {
            type: String,
            default: "请选择",
        },
        value: {
            type: Array,
        },
        options: {
            type: Array,
            default: () => [],
        },
        props: {
            type: Object,
            default: () => ({}),
        },
        filterMethod: {
            type: Function,
        },
        initInputText: {
            type: [Array, String],
        },
        separator: {
            type: String,
            default: "/",
        },
    },
    filters: {
        inputTextFilter(data, labelName, separator) {
            if (Array.isArray(data)) {
                return data.map((item) => item[labelName]).join(separator);
            }

            return data[labelName];
        },
    },
    data() {
        return {
            treeModel: MODE_TYPE.select,
            visible: false,
            filterKey: "",
            filterOptions: [],
            tempCheckedKeys: this.value || [], // tree组件选择绑定值
            // inputText: this.initInputText || [],
            inputText: [],
        };
    },
    computed: {
        checkedKeys: {
            get() {
                return this.value; // TODO 判断是否全路径
            },
            set(n) {
                this.$emit("input", n ? [...n] : n); // TODO 判断是否全路径
            },
        },
        labelName() {
            return this.props.label || "label";
        },
        idName() {
            return this.props.value || "id";
        },
        multiple() {
            return this.props.multiple;
        },
        emitPath() {
            return this.props.emitPath;
        },
        // 是否子父节点不关联
        checkStrictly() {
            return this.props.checkStrictly;
        },
        showText() {
            let flag = false;
            if (this.inputText && this.inputText.length) {
                flag = true;
            }
            return flag;
        },
        getDisabled() {
            if (this.disabled) {
                return this.disabled;
            }

            let parent = this.$parent;

            while (parent && parent.$options.name !== "ElForm") {
                parent = parent.$parent;
            }

            return parent.disabled;
        },
    },
    watch: {
        value(n) {
            let keys = [];
            if (n) {
                // this.tempCheckedKeys = n;
                keys = [...n];
            }
            this.setTree(keys);
            // this.updateInput();
            this.updateInputByTreeCheckedKeys();
        },
        // initInputText(n) {
        //     if (n) {
        //         this.inputText = n;
        //     }
        // },
    },

    methods: {
        renderContent(h, { node, data, store }) {
            const itemSelect = (e) => {
                return e.stopPropagation();
            };

            const nodeChange = (v) => {
                if (!this.multiple && v) {
                    this.clearTree();
                }
                node.checked = v;
                 /* 父子节点勾选时关联 */
                if (this.props.connected) {
                    if (node.childNodes.length) {
                        node.childNodes.forEach((item) => {
                            item.checked = v;
                        });
                    }
                    let arr = node.parent.childNodes.map((item) => {
                        return item.checked;
                    });
                    if (arr.length === node.parent.childNodes.length) {
                        arr = Array.from(new Set(arr));
                        if (arr.length === 1) {
                            node.parent.checked = arr[0];
                        } else {
                            node.parent.checked = false;
                        }
                    }
                }
            };
            // if(node.parent.level !== 0 && !node.parent.loaded) {
            // 	node.checked = node.parent.checked
            // }

            let checkBox = (
                <el-checkbox
                    nativeOn-click={itemSelect}
                    style="margin-right: 8px;"
                    value={node.checked}
                    disabled={node.data.disabled}
                    on-input={nodeChange}
                ></el-checkbox>
            );

            if (!this.checkStrictly && !node.isLeaf) {
                checkBox = null;
            }
            let label = node[this.labelName] || node?.data[this.labelName] || '';
            if (this.props.labelHandle) {
                label = this.props.labelHandle(node);
            }

            return (
                <div class="render_label">
                    {checkBox}
                    <span class="custom-tree-node">
                        <span>{label}</span>
                    </span>
                </div>
            );
        },
        onSelectClick(e) {
            if (this.getDisabled) {
                e.stopPropagation();
                return;
            }
            this.visible = !this.visible;
        },
        handleNodeClick() {},
        // 搜索事件
        filterClick(option) {
            let ref = this.$refs[this.treeModel];
            let hasKeyFlag = Boolean(this.filterKey);
            if (this.filterMethod) {
                if (!hasKeyFlag) {
                    this.updateFilterTree([], Boolean(this.filterKey));
                    return;
                }
                this.filterMethod(this.filterKey).then((options) => {
                    this.updateFilterTree(options, Boolean(this.filterKey));
                });
            } else {
                // 执行tree搜索方法 filter
                ref.filter(option);
            }
        },
        // 根据isFilter更新组件状态为filter模式或select模式
        updateFilterTree(options, isFilter) {
            if (isFilter) {
                this.filterOptions = options || [];
                this.treeModel = MODE_TYPE.filter;
            } else {
                this.filterOptions = [];
                this.treeModel = MODE_TYPE.select;
            }
        },
        // 选择框选择事件
        checkChange(data, selectFlag, childrenSelectedFlag) {
            let id = _.get(data, this.idName);
            if (selectFlag) {
                if (this.tempCheckedKeys.push(id));
            } else {
                _.remove(this.tempCheckedKeys, (item) => item === id);
            }
        },
        currentChange(data, node) {},
        closePopover() {
            let ref = this.$refs.popover;
            ref && (ref.showPopper = false);
        },
        // 确定
        onConfirm() {
            // let ref = this.$refs[this.treeModel];
            // let selectedNodes = ref.getCheckedNodes();

            this.updateValues(this.tempCheckedKeys);
            this.closePopover();
        },
        // 选择框清空事件
        // TODO 如果是check-strictly $emit选中的值是做选中 节点路径处理
        clearHandle() {
            this.clearTree();
            this.tempCheckedKeys = [];
            this.updateValues();
        },
        clearTree() {
            let ref = this.$refs[this.treeModel];
            (this.tempCheckedKeys || []).forEach((key) => {
                ref.setChecked(key, false);
            });
        },
        // 设置树选择状态
        setTree(selected) {
            this.clearTree();
            this.tempCheckedKeys = selected;
            if (!selected && !selected.length) {
                return;
            }
            this.$nextTick(() => {
                let ref = this.$refs[this.treeModel];
                (selected || []).forEach((key) => {
                    ref.setChecked(key, true);
                });
            });
        },
        // 更新组件数据
        updateValues(checkeds) {
            if (!checkeds || !checkeds.length) {
                this.checkedKeys = null;
                this.inputText = null;
            } else {
                this.checkedKeys = [...checkeds];
                // this.updateInput(inputText);
                this.updateInputByTreeCheckedKeys();
            }
            this.$emit("onConfirm", this.checkedKeys, this.inputText);
        },
        // updateInput(inputText){
        //     // if (inputText) {
        //     //     this.inputText = inputText;
        //     //     return;
        //     // }
        //     this.updateInputByTreeCheckedKeys();
        // },
        updateInputByTreeCheckedKeys: _.debounce(function () {
            let ref = this.$refs[this.treeModel];

            let selectedNodes = ref.getCheckedNodes();

            if (this.initInputText && this.initInputText.length) {
                let nodesOut = this.initInputText.filter((obj) => {
                    return _.includes(this.tempCheckedKeys, obj.id);
                });
                nodesOut = nodesOut.filter((item) => {
                    return !_.includes(
                        selectedNodes.map((item) => {
                            return item.id;
                        }),
                        item.id
                    );
                });

                selectedNodes = [...selectedNodes, ...nodesOut];
            }

            if (this.emitPath) {
                // 根据treeMap 获取选择的节点路径
                let treeMap = {};
                if (this.initInputText && this.initInputText.length) {
                    selectedNodes.forEach((item) => {
                        treeMap[item.id] = { data: item };
                    });
                }
                treeMap = {
                    ...treeMap,
                    ...(_.get(ref, "store.nodesMap") || {}),
                };

                Object.keys(treeMap).forEach((key) => {
                    treeMap[key] = treeMap[key].data;
                });

                let pathNodes = selectedNodes.map((item) => {
                    return getPathByLeafId(item.id, treeMap);
                });

                this.inputText = pathNodes;
            } else {
                this.inputText = selectedNodes;
            }
        }, 500),
    },
};
</script>
<style lang="scss" scoped>
.selectWrapper {
    height: 380px;
}
.tree-input-wrapper {
    font-size: 12px;
}
.fixHeight {
    height: 28px;
}
.showMore {
    overflow: auto;
    white-space: normal;
}
.input-click-select.disabled {
    background-color: #f5f7fa;
    color: #c0c4cc;
    cursor: not-allowed;
}
.input-click-select.disabled:hover {
    border-color: #e4e7ed;
}
// .selectWrapper {
//     &::v-deep {
//         .el-tree-node__content {
//             .el-checkbox {
//                 display: none;
//             }
//         }
//     }
// }
.footer {
    display: fixed;
    bottom: 0;
    text-align: center;
}
</style>
